package org.example.myleet.p641;

public class MyCircularDeque {

    private final int[] store;
    private int front;
    private int rear;
    private final int size;

    public MyCircularDeque(int k) {
        store = new int[k + 1];
        //front指针在插入数据时向左移动，front指针右边的是数据，左边的是空位
        front = 0;
        //rear指针在插入数据时向右移动，rear指针左边的是数据，右边的是空位
        rear = 1;
        //实际判断过程中由于有两个指针，因此需要实际申请数组的size = k + 1
        size = k + 1;
    }

    public boolean insertFront(int value) {
        if (isFull()) {
            return false;
        }
        //记录到队头位置，并将front指针向左移动一位
        store[front] = value;
        front = (front - 1 + size) % size;
        return true;
    }

    public boolean insertLast(int value) {
        if (isFull()) {
            return false;
        }
        //记录到队尾位置，并将rear指针向右移动一位
        store[rear] = value;
        rear = (rear + 1) % size;
        return true;
    }

    public boolean deleteFront() {
        if (isEmpty()) {
            return false;
        }
        //front指针向右边移动一位，相当于删除队头数据
        front = (front + 1) % size;
        return true;
    }

    public boolean deleteLast() {
        if (isEmpty()) {
            return false;
        }
        //rear指针向左边移动一位，相当于删除队尾数据
        rear = (rear - 1 + size) % size;
        return true;
    }

    public int getFront() {
        if (isEmpty()) {
            return -1;
        }
        //front指针的右边一位即为队列头数据
        return store[(front + 1) % size];
    }

    public int getRear() {
        if (isEmpty()) {
            return -1;
        }
        //rear指针的左边一位即为队列尾数据
        return store[(rear - 1 + size) % size];
    }

    public boolean isEmpty() {
        //如果rear指针向左移动一位时（模拟删除尾部）与front指针重合，说明队列是空的
        return (rear - 1 + size) % size == front;
    }

    public boolean isFull() {
        //如果rear指针与front指针重合，说明队列是满的
        return rear == front;
    }
}
